home *** CD-ROM | disk | FTP | other *** search
/ Aminet 7 / Aminet 7 - August 1995.iso / Aminet / util / cli / BaseConv_37_1.lha / BaseConv / BaseConv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-05  |  6.0 KB  |  397 lines

  1. #include "BaseConv.h"
  2.  
  3. STXT VersTag[]      = "$VER: " VSTR;
  4. STXT Compiled[]     = "Compiled on " __DATE__ " at " __TIME__;
  5. STXT Copyright[]    = "Copyright © 1994,95 Klaus Alexander Seistrup @ Magnetic Ink";
  6. STXT EMail[]        = "E-mail: kas@mink.ping.dk";
  7.  
  8. STXT Template[]        = "BaseFrom/A,BaseTo/A,Numbers/A/M,-u=ToUpper/S,-l=ToLower/S";
  9. STXT ExtHelp[]        = \
  10. "\n" \
  11. "›33mUSAGE:›0m ›1mBaseConv›0m <BaseFrom> <BaseTo> <Number1> [<Number2>...<NumberN>]\n" \
  12. "\n" \
  13. "\t<›3mBaseFrom›0m> and <›3mBaseTo›0m> must be numbers between 2 and 36\n" \
  14. "\t<›3mNumber›0m> must be lower than 2^32\n\n" \
  15. "BaseFrom/A,BaseTo/A,Numbers/A/M,-u=ToUpper/S,-l=ToLower/S";
  16.  
  17. STXT OrigAuthor[]    = \
  18. "Original author:\n" \
  19. "Xavier SIRVENT" \
  20. "71 Cours Saint Andr‚" \
  21. "F-38800 Le Pont de Claix";
  22.  
  23.  
  24. CFG GlobCFG;
  25.  
  26.  
  27.  
  28. Prototype LONG     FPrintF(BPTR,TEXT *,...);
  29. //
  30. LONG FPrintF(fh,ctl,...)
  31. BPTR fh;
  32. TEXT *ctl;
  33. {
  34.     LONG cnt;
  35.     va_list va;
  36.  
  37.     va_start(va,ctl);
  38.     cnt = VFPrintf(fh,ctl,va);
  39.     va_end(va);
  40.  
  41.     return (cnt);
  42. }
  43.  
  44.  
  45. Prototype VOID     Usage(CFG *);
  46. //
  47. VOID 
  48. Usage(cfg)
  49. CFG *cfg;
  50. {
  51.     BPTR fh = cfg->fe ? cfg->fe : cfg->fo;
  52.  
  53.     if (fh)
  54.         FPuts(fh,ExtHelp);
  55.  
  56.     Cleanup(cfg);
  57. }
  58.  
  59.  
  60. Prototype ULONG     Rank(TEXT,ULONG);
  61. //
  62. ULONG
  63. Rank(charac,BaseFrom)    // Returns the value of the "charac" given in base "BaseFrom"
  64. TEXT charac;
  65. ULONG BaseFrom;
  66. {
  67.  
  68.     LONG i = -1L;
  69.     TEXT c = ToLower(charac);
  70.  
  71.     if (c >= '0' && c <= '9')
  72.         i = c - '0';
  73.     else if (c >= 'a' && c <= 'z')
  74.         i = c - ('a' - 10);
  75.  
  76.     if ((i == -1) || (i >= BaseFrom))
  77.     {
  78.         CFG *cfg = &GlobCFG;
  79.         BPTR fh  = cfg->fe ? cfg->fe : cfg->fo;
  80.  
  81.         cfg->RC  = RETURN_WARN;
  82.         cfg->R2     = ERROR_BAD_NUMBER;
  83.         cfg->ErrMsg = NULL;
  84.  
  85.         c = cfg->ToLower ? ToLower(c) : ToUpper(c);
  86.  
  87.         if (fh)
  88.             FPrintF(fh,"›33mERROR:›0m ›1m%lc›0m is forbidden in base ›1m%ld›0m\n",c,BaseFrom);
  89.  
  90.         Cleanup(cfg);
  91.     }
  92.     return ((ULONG) i);
  93. }
  94.  
  95.  
  96. /*
  97. **    CSI = ›
  98. */
  99.  
  100.  
  101. Prototype ULONG     ToBase10(TEXT *,ULONG);
  102. //
  103. ULONG
  104. ToBase10(num,BaseFrom)    // Returns base 10 of "num" given in base "BaseFrom"
  105. TEXT *num;
  106. ULONG BaseFrom;
  107. {
  108.     ULONG i;
  109.     ULONG res1 = 0L;
  110.     ULONG slen = strlen(num);
  111.  
  112.     for (i = 0l ; i < slen ; ++i)
  113.     {
  114.         ULONG res2 = UMul32(res1,BaseFrom) + Rank(num[i],BaseFrom);
  115.  
  116.         if (res2 <= res1)
  117.         {
  118.             CFG *cfg = &GlobCFG;
  119.             BPTR fh  = cfg->fe ? cfg->fe : cfg->fo;
  120.  
  121.             cfg->RC  = RETURN_WARN;
  122.             cfg->R2     = ERROR_BAD_NUMBER;
  123.             cfg->ErrMsg = NULL;
  124.  
  125.             if (fh)
  126.                 FPrintF(fh,"›33mERROR:›0m ›1m%s›0m > ›1m2^32›0m\n",num);
  127.  
  128.             Cleanup(cfg);
  129.         }
  130.         res1 = res2;
  131.     }
  132.     return (res1);
  133. }
  134.  
  135.  
  136.  
  137. Prototype TEXT    *FromBase10(ULONG,ULONG);
  138. //
  139. TEXT *
  140. FromBase10(num,BaseTo)    // Display the number in BaseTo
  141. ULONG num,BaseTo;
  142. {
  143.     STATIC TEXT RevBuf[128];
  144.  
  145.     TEXT  tmp;
  146.     TEXT *res = RevBuf;
  147.  
  148.     TEXT uchar = GlobCFG.ToLower ? 'a' : 'A';
  149.  
  150.     ULONG i = 0L;
  151.     ULONG j = 0L;
  152.     ULONG mod = 0L;
  153.  
  154.     /*
  155.     ** The result is generated in reverse order
  156.     */
  157.     while ((num != 0L) && (i < 80L))
  158.     {
  159.         mod = UMod32(num,BaseTo);
  160.  
  161.         res[i++] = (mod <= 9) ? (mod + '0') : (mod - (10 - uchar));
  162.         res[i] = 0;
  163.  
  164.         num = UDiv32(num,BaseTo);
  165.     }
  166.  
  167.     /*
  168.     ** making the result right order 
  169.     */
  170.     while (j < (i >> 1))
  171.     {
  172.         ULONG k = i - j - 1;
  173.  
  174.         tmp = res[j];
  175.  
  176.         res[j] = res[k];
  177.         res[k] = tmp;
  178.  
  179.         ++j;
  180.     }
  181.     return (res);
  182. }
  183.  
  184.  
  185.  
  186. Prototype VOID     Cleanup(CFG *);
  187. //
  188. VOID
  189. Cleanup(cfg)
  190. CFG *cfg;
  191. {
  192.     BPTR fh = NULL;
  193.  
  194.     if (cfg->Args)
  195.         FreeArgs(cfg->Args);
  196.  
  197.     if (cfg->DObj)
  198.         FreeDosObject(DOS_RDARGS,cfg->DObj);
  199.  
  200.     if (cfg->fe)
  201.     {
  202.         fh = SelectOutput(cfg->fe);
  203.  
  204.         if (fh)
  205.             Flush(fh);
  206.     }
  207.  
  208.     if (cfg->R2 && cfg->RC != RETURN_WARN)
  209.         PrintFault(cfg->R2,cfg->ErrMsg);
  210.     else
  211.     if (cfg->ErrMsg)
  212.         PutStr(cfg->ErrMsg);
  213.  
  214.     if (cfg->fe)
  215.     {
  216.         fh = SelectOutput(fh);
  217.  
  218.         if (fh)
  219.             Flush(fh);
  220.  
  221.         if (cfg->CloseFE)
  222.             Close(cfg->fe);
  223.     }
  224.     SetIoErr(cfg->R2);
  225.  
  226.     _exit(cfg->RC);
  227. }
  228.  
  229.  
  230. Prototype TEXT    *StrLower(TEXT *);
  231. //
  232. TEXT *
  233. StrLower(str)
  234. TEXT *str;
  235. {
  236.     if (str)
  237.     {
  238.         TEXT *low = str;
  239.  
  240.         while (*str)
  241.         {
  242.             *str = ToLower(*str);
  243.             ++str;
  244.         }
  245.         return (low);
  246.     }
  247.     return (NULL);
  248. }
  249.  
  250.  
  251. Prototype TEXT    *StrUpper(TEXT *);
  252. //
  253. TEXT *
  254. StrUpper(str)
  255. TEXT *str;
  256. {
  257.     if (str)
  258.     {
  259.         TEXT *upr = str;
  260.  
  261.         while (*str)
  262.         {
  263.             *str = ToUpper(*str);
  264.             ++str;
  265.         }
  266.         return (upr);
  267.     }
  268.     return (NULL);
  269. }
  270.  
  271.  
  272.  
  273. Prototype CFG    *InitCFG(CFG *);
  274. //
  275. CFG *
  276. InitCFG(cfg)
  277. CFG *cfg;
  278. {
  279.     cfg->fi = Input();
  280.     cfg->fo = Output();
  281.     cfg->fe = ((struct Process *)FindTask(NULL))->pr_CES;
  282.  
  283.     if (cfg->fe == NULL)
  284.     {
  285.         cfg->fe = Open("Console:",MODE_READWRITE);
  286.  
  287.         if (cfg->fe)
  288.             cfg->CloseFE = TRUE;
  289.         else
  290.             cfg->fe = cfg->fo;
  291.     }
  292.     cfg->ErrMsg = VersTag+6;
  293.  
  294.     if ((cfg->DObj = (ARGS *)AllocDosObject(DOS_RDARGS,NULL)) == NULL)
  295.     {
  296.         cfg->RC = RETURN_ERROR;
  297.         cfg->R2 = ERROR_NO_FREE_STORE;
  298.         cfg->ErrMsg = "AllocDosObject()";
  299.  
  300.         Cleanup(cfg);
  301.     }
  302.     cfg->DObj->RDA_ExtHelp = ExtHelp;
  303.  
  304.     if ((cfg->Args = ReadArgs(Template,(LONG *)&(cfg->From),cfg->DObj)) == NULL)
  305.     {
  306.         cfg->RC = RETURN_ERROR;
  307.         cfg->R2 = IoErr();
  308.  
  309.         Cleanup(cfg);
  310.     }
  311.  
  312.     if (cfg->ToLower)
  313.         cfg->ToLower = TRUE;
  314.  
  315.     if (cfg->ToUpper)
  316.         cfg->ToUpper = TRUE;
  317.  
  318.     if (!(cfg->ToLower ^ cfg->ToUpper))
  319.     {
  320.         cfg->ToLower = TRUE;
  321.         cfg->ToUpper = FALSE;
  322.     }
  323.  
  324.     cfg->From = cfg->ToLower ? StrLower(cfg->From) : StrUpper(cfg->From);
  325.     cfg->To      = cfg->ToLower ? StrLower(cfg->To)   : StrUpper(cfg->To);
  326.     {
  327.         ULONG i = 0L;
  328.         TEXT **num = cfg->Number;
  329.  
  330.         while (num[i])
  331.         {
  332.             num[i] = cfg->ToLower ? StrLower(num[i]) : StrUpper(num[i]);
  333.             ++i;
  334.         }
  335.     }
  336.     return (cfg);
  337. }
  338.  
  339.  
  340.  
  341.  
  342. Prototype LONG    _main(VOID);
  343. //
  344. LONG
  345. _main(VOID)
  346. {
  347.     if (Cli())
  348.     {
  349.         ULONG i  = 0L;
  350.         CFG *cfg = InitCFG(&GlobCFG);
  351.  
  352.         StrToLong(cfg->From,&(cfg->BaseFrom));
  353.         StrToLong(cfg->To,&(cfg->BaseTo));
  354.  
  355.         if ((cfg->BaseFrom > 36) || (cfg->BaseTo > 36) || (cfg->BaseFrom < 2) || (cfg->BaseTo < 2))
  356.         {
  357.             BPTR fh  = cfg->fe ? cfg->fe : cfg->fo;
  358.  
  359.             cfg->RC  = RETURN_WARN;
  360.             cfg->R2     = ERROR_BAD_NUMBER;
  361.             cfg->ErrMsg = NULL;
  362.  
  363.             if (fh)
  364.                 FPuts(fh,"›33mERROR:›0m <›3mBaseFrom›0m> and <›3mBaseTo›0m> must be in [2..36]\n");
  365.  
  366.             Cleanup(cfg);
  367.         }
  368.  
  369.         while (cfg->Number[i])
  370.         {
  371.             FPrintf(cfg->fo,"%s = %s\n",cfg->Number[i],FromBase10(ToBase10(cfg->Number[i],cfg->BaseFrom),cfg->BaseTo));
  372.             ++i;
  373.  
  374.             if (CheckSignal(SIGBREAKF_CTRL_C))
  375.             {
  376.                 cfg->RC = 1L;
  377.                 cfg->R2 = 304L;
  378.  
  379.                 cfg->ErrMsg = NULL;
  380.  
  381.                 Cleanup(cfg);
  382.             }
  383.         }
  384.         cfg->RC = 0L;
  385.         cfg->R2 = 0L;
  386.         cfg->ErrMsg = 0L;
  387.  
  388.         Cleanup(cfg);
  389.     }
  390.     return (-1L);
  391. }
  392.  
  393.  
  394. /*
  395. **    EOF
  396. */
  397.